package org.ct.gui.tables;

import java.util.List;

import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;

import org.ct.Globals;
import org.ct.dataobjects.DataObject;
import org.hibernate.Query;
import org.hibernate.Session;

@SuppressWarnings("serial")
public abstract class DataTable<T extends DataObject> extends JTable {
	protected List<? extends T> data;
	private Class<? extends T> dataObjectsClass;

	protected abstract String[] getColumnNames();

	protected abstract String getTableCellStringAt(int rowIndex, int columnIndex);

	protected abstract void setTableCellStringAt(int rowIndex, int columnIndex, String value);

	public DataTable(Class<? extends T> dataObjectsClass) {
		super();
		this.dataObjectsClass = dataObjectsClass;
		data = getAllObjectsFromDatabase();
		setupLayout();
		setModel(new DataTableModel());
	}

	protected void setupLayout() {
		// TODO Auto-generated method stub

	}

	protected List<? extends T> getAllObjectsFromDatabase() {
		Session session = Globals.hibSessionFactory.openSession();
		Query query = session.createQuery("from " + dataObjectsClass.getCanonicalName());
		List<? extends T> result = query.list();
		session.close();
		return result;
	}

	class DataTableModel extends AbstractTableModel {

		@Override
		public int getColumnCount() {
			return getColumnNames().length;
		}

		@Override
		public int getRowCount() {
			if (data == null) return 0;
			return data.size();
		}

		@Override
		public Object getValueAt(int rowIndex, int columnIndex) {
			return getTableCellStringAt(rowIndex, columnIndex);
		}

		@Override
		public String getColumnName(int index) {
			return getColumnNames()[index];
		}

		@Override
		public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
			setTableCellStringAt(rowIndex, columnIndex, aValue.toString());
		}

	}
}
